/*
 * PipeReader.cpp
 *
 *  Created on: 2020年11月16日
 *      Author: chuanjiang.zh
 */

#include "PipeReader.h"
#include <stdio.h>
#include "TStringUtil.h"

#ifdef WIN32
static FILE * popen(const char * command, const char * type)
{
	return _popen(command, type);
}

static int pclose(FILE * f)
{
	return _pclose(f);
}

#else
	
#endif //

static const size_t BUFFER_SIZE = 1024 * 16;


PipeReader::PipeReader()
{
}

PipeReader::~PipeReader()
{
}

bool PipeReader::read(const std::string& cmd, std::string& text)
{
    bool got = false;
	FILE* pFile = popen(cmd.c_str(), "r");
	if (pFile)
	{
		while (true)
		{
            char buffer[BUFFER_SIZE] = {0};
			size_t count = fread(buffer, 1, BUFFER_SIZE, pFile);
			if (count == 0)
			{
				break;
			}

            std::string line(buffer, count);
            text.append(line);

			if (count != BUFFER_SIZE)
			{
				break;
			}
		}

		pclose(pFile);
		got = true;
	}
	return got;
}

bool PipeReader::read(const std::string& cmd, std::vector<std::string>& lines)
{
    LineHandler pred = [] (const std::string& line)
    {
        return true;
    };
    return read(cmd, pred, lines);
}

bool PipeReader::readOne(const std::string& cmd, LineHandler pred, std::string& text)
{
    bool got = false;
	FILE* pFile = popen(cmd.c_str(), "r");
	if (pFile)
	{
		while (true)
		{
            char buffer[BUFFER_SIZE] = {0};
			const char* ptr = fgets(buffer, BUFFER_SIZE, pFile);
			if (ptr == nullptr)
			{
				break;
			}

            std::string line(ptr);
			comn::StringUtil::trim(line);

            if (pred(line))
            {
                text = line;
				got = true;
                break;
            }
		}

		pclose(pFile);
	}
	return got;
}

bool PipeReader::read(const std::string& cmd, LineHandler pred, std::vector<std::string>& lines)
{
	//printf("PipeReader::read. %s\n", cmd.c_str());

    bool got = false;
	FILE* pFile = popen(cmd.c_str(), "r");
	if (pFile)
	{
		while (true)
		{
            char buffer[BUFFER_SIZE] = {0};
			const char* ptr = fgets(buffer, BUFFER_SIZE, pFile);
			if (ptr == nullptr)
			{
				break;
			}

            std::string line(ptr);
			comn::StringUtil::trim(line);

            if (pred(line))
            {
                lines.push_back(line);
            }
		}

		pclose(pFile);
		got = true;
	}
	return got;
}